/**
 * 所有支持的颜色
 */
declare global {
    const enum ConsoleColor {
        white = '#ffffff',
        blue = '#8dc5e3',
        green = '#6b9955',
        yellow = '#c5c599',
        red = '#ef9a9a',
        gray = '#a4a4a4',
        lightgray = '#e6e6e6'
    }
}

let logLevel = 0;

const DEBUG_LOG_LEVEL = 0;
const INFO_LOG_LEVEL = 1;
const STATUS_LOG_LEVEL = 2;
const ERROR_LOG_LEVEL = 3;

/**
 * 通用控制台日志模块
 */
export class Logger {

    /**
     * 给字符串以 HTML 格式化
     * @param str 要格式化的字符串
     * @param color 颜色
     * @param bold 是否加粗
     */
    public static colorize(str: string, color = ConsoleColor.white, bold = false) {
        return `<text style="color: ${color}; font-weight: ${bold ? 'bold' : 'normal'}">${str}</text>`;
    }

    /**
     * 稍微处理一下标题
     */
    private static processTitle(title?: string, color = ConsoleColor.white, _default = '') {
        return title ? this.colorize(`【${title.toUpperCase()}】`, color) : _default;
    }

    private static getTime() {
        return this.colorize('' + Game.time, ConsoleColor.gray, false);
    }

    /**
     * 模板函数，如 `<Game tick> [TITLE] TEXT`
     */
    private static template(text: string, title?: string, color = ConsoleColor.white, colorizeText = false) {
        const processedText = colorizeText ? this.colorize(text, color) : text;
        return `${this.getTime()} ${this.processTitle(title, color)} ${processedText}`;
    }

    // 不同等级的方法 ========================================================================

    static debug(text: string, title?: string) {
        if (logLevel >= DEBUG_LOG_LEVEL) {
            console.log(this.template(text, title, ConsoleColor.lightgray, true));
        }
    }

    static info(text: string, title?: string) {
        if (logLevel >= INFO_LOG_LEVEL) {
            console.log(this.template(text, title, ConsoleColor.blue));
        }
    }

    static success(text: string, title?: string, notify = false) {
        if (logLevel >= STATUS_LOG_LEVEL) {
            console.log(this.template(text, title, ConsoleColor.green, true));
            if (notify) {
                this.notify(`【${title}】 ${text}`);
            }
        }
    }

    static warn(text: string, title?: string, notify = false) {
        if (logLevel >= STATUS_LOG_LEVEL) {
            console.log(this.template(text, title, ConsoleColor.yellow, true));
            if (notify) {
                this.notify(`【${title}】 ${text}`);
            }
        }
    }
    /** @alias Logger.warn */
    static fail(text: string, title?: string, notify = false) {
        this.warn('FAIL: ' + text, title, notify);
    }

    static error(text: string, title?: string, notify = true) {
        console.log(this.template(text, title, ConsoleColor.red, true));
        if (notify) {
            this.notify(`【${title}】 ${text}`);
        }
    }

    static notify(content: string) {
        // 获取当前的时间
        const curDate = new Date;
        const dateString = `${curDate.getHours()}:${curDate.getMinutes()}:${curDate.getSeconds()}`;
        // 发送通知
        Game.notify(`${dateString} (#${Game.time}) | ${content}`);
    }

    // 设置日志等级

    static setLogLevel(level: number) {
        logLevel = Math.max(DEBUG_LOG_LEVEL, Math.min(ERROR_LOG_LEVEL, level));
    }

    static getLogLevel() {
        return logLevel;
    }
}

export const $render = Logger.colorize;

/**
 * 根据数量的关系渲染输出，如 `$renderNumber(x, { bottom: 0, top: 100 })`，x=0 时将被渲染
 * 成红色，x=100 时将被渲染成绿色，x=50 时将被渲染成黄色。
 */
export const $renderNumber = (x: number, { bottom = 0, top = 100 } = {}) => {
    const ratio = (x - bottom) / (top - bottom);
    if (ratio < 0.3) {
        return Logger.colorize(x.toString(), ConsoleColor.red);
    }
    else if (ratio < 0.7) {
        return Logger.colorize(x.toString(), ConsoleColor.yellow);
    }
    else {
        return Logger.colorize(x.toString(), ConsoleColor.green);
    }
};
